<template>
  <view class="xen-autocomplete">
    <!-- 输入框 -->
    <input
      class="autocomplete-input"
      :class="{ 'has-error': hasError, 'is-focused': isFocused }"
      type="text"
      :value="displayValue"
      :placeholder="placeholder"
      @input="handleInput"
      @focus="handleFocus"
      @blur="handleBlur"
    />

    <!-- 下拉选项列表 -->
    <view
      v-if="showDropdown && filteredOptions.length > 0"
      class="dropdown-list"
      @touchstart="handleDropdownTouch"
      @touchmove="handleDropdownTouch"
      @touchend="handleDropdownTouch"
      @click="handleDropdownTouch"
    >
      <scroll-view
        scroll-y
        class="dropdown-scroll"
        @touchstart="handleDropdownTouch"
        @touchmove="handleDropdownTouch"
        @touchend="handleDropdownTouch"
      >
        <view
          v-for="(option, index) in filteredOptions"
          :key="option.value"
          class="dropdown-item"
          :class="{ 'is-selected': selectedIndex === index }"
          @click="selectOption(option)"
        >
          <text class="option-text">{{ option.text }}</text>
          <text v-if="option.subtitle" class="option-subtitle">{{
            option.subtitle
          }}</text>
        </view>

        <!-- 无匹配结果 -->
        <view
          v-if="filteredOptions.length === 0 && searchQuery"
          class="no-results"
        >
          <text class="no-results-text">无匹配结果</text>
        </view>

        <!-- 加载状态 -->
        <view v-if="loading" class="loading-item">
          <text class="loading-text">搜索中...</text>
        </view>
      </scroll-view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, computed, watch } from "vue";

// 选项数据接口
export interface AutoCompleteOption {
  value: string;
  text: string;
  subtitle?: string;
  [key: string]: any;
}

// Props 定义
interface Props {
  modelValue?: string;
  placeholder?: string;
  options?: AutoCompleteOption[];
  hasError?: boolean;
  disabled?: boolean;
  minSearchLength?: number;
  debounceTime?: number;
  searchApi?: (query: string) => Promise<AutoCompleteOption[]>;
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: "",
  placeholder: "请输入并选择",
  options: () => [],
  hasError: false,
  disabled: false,
  minSearchLength: 1,
  debounceTime: 300,
});

// Emits 定义
const emit = defineEmits<{
  "update:modelValue": [value: string];
  change: [value: string, option: AutoCompleteOption | null];
  search: [query: string];
  focus: [];
  blur: [];
}>();

// 响应式数据
const displayValue = ref("");
const searchQuery = ref("");
const isFocused = ref(false);
const showDropdown = ref(false);
const selectedIndex = ref(-1);
const loading = ref(false);
const debounceTimer = ref<number | null>(null);
const isUserInput = ref(false); // 标记是否为用户输入
const searchResults = ref<AutoCompleteOption[]>([]); // API搜索结果
const isDropdownTouching = ref(false); // 标记是否正在触摸下拉列表

// 计算属性
const filteredOptions = computed(() => {
  // 如果有API搜索结果，优先使用搜索结果
  if (searchResults.value.length > 0) {
    return searchResults.value;
  }

  // 否则使用本地过滤
  if (!searchQuery.value || searchQuery.value.length < props.minSearchLength) {
    return props.options;
  }

  return props.options.filter(
    (option) =>
      option.text.toLowerCase().includes(searchQuery.value.toLowerCase()) ||
      (option.subtitle &&
        option.subtitle
          .toLowerCase()
          .includes(searchQuery.value.toLowerCase())),
  );
});

// 监听modelValue变化
watch(
  () => props.modelValue,
  (newValue) => {
    // 标记这不是用户输入，避免触发搜索
    isUserInput.value = false;

    if (newValue) {
      // 根据value找到对应的option显示text
      const option = props.options.find((opt) => opt.value === newValue);
      displayValue.value = option ? option.text : newValue;
      // 程序化设置值时，不设置searchQuery，避免显示下拉列表
      searchQuery.value = "";
    } else {
      displayValue.value = "";
      searchQuery.value = "";
    }

    // 程序化设置值时隐藏下拉列表
    showDropdown.value = false;
    // 清空搜索结果
    searchResults.value = [];
  },
  { immediate: true },
);

// 输入处理
const handleInput = (event: any) => {
  const value = event.detail.value;

  // 标记这是用户输入
  isUserInput.value = true;

  displayValue.value = value;
  searchQuery.value = value;

  // 清除之前的定时器
  if (debounceTimer.value) {
    clearTimeout(debounceTimer.value);
  }

  // 清空之前的搜索结果
  searchResults.value = [];

  // 只在用户输入且有内容时才触发搜索
  if (value && value.length >= props.minSearchLength) {
    // 设置防抖
    debounceTimer.value = setTimeout(() => {
      performSearch(value);
    }, props.debounceTime);

    // 显示下拉列表
    showDropdown.value = true;
  } else {
    // 输入为空或长度不足时，隐藏下拉列表
    showDropdown.value = false;
  }

  selectedIndex.value = -1;

  // 如果输入为空，清空选择
  if (!value) {
    emit("update:modelValue", "");
    emit("change", "", null);
  }
};

// 执行搜索
const performSearch = async (query: string) => {
  // 只在用户主动输入时才执行搜索
  if (!isUserInput.value || !query || query.length < props.minSearchLength) {
    return;
  }

  emit("search", query);

  // 如果有API搜索函数，调用它
  if (props.searchApi) {
    try {
      loading.value = true;
      const results = await props.searchApi(query);
      // 更新搜索结果
      searchResults.value = results || [];
    } catch (error) {
      console.error("搜索失败:", error);
      searchResults.value = [];
    } finally {
      loading.value = false;
    }
  }
};

// 焦点处理
const handleFocus = () => {
  isFocused.value = true;
  // 只有在有搜索查询且有结果时才显示下拉列表
  if (searchQuery.value && filteredOptions.value.length > 0) {
    showDropdown.value = true;
  }
  emit("focus");
};

const handleBlur = () => {
  // 如果正在触摸下拉列表，不隐藏下拉列表
  if (isDropdownTouching.value) {
    return;
  }

  // 延迟隐藏下拉列表，以便点击选项时能正常触发
  setTimeout(() => {
    if (!isDropdownTouching.value) {
      isFocused.value = false;
      showDropdown.value = false;
      selectedIndex.value = -1;
    }
  }, 200);
  emit("blur");
};

// 下拉列表触摸处理
const handleDropdownTouch = (event: any) => {
  // 阻止事件冒泡，防止触发输入框的blur事件
  if (event && event.stopPropagation) {
    event.stopPropagation();
  }

  // 标记正在触摸下拉列表
  isDropdownTouching.value = true;

  // 设置一个短暂的延迟后重置状态
  setTimeout(() => {
    isDropdownTouching.value = false;
  }, 100);
};

// 选择选项
const selectOption = (option: AutoCompleteOption) => {
  // 标记这不是用户输入，避免触发搜索
  isUserInput.value = false;

  displayValue.value = option.text;
  searchQuery.value = option.text;
  showDropdown.value = false;
  selectedIndex.value = -1;

  emit("update:modelValue", option.value);
  emit("change", option.value, option);
};

// 清空输入
const clear = () => {
  // 标记这不是用户输入，避免触发搜索
  isUserInput.value = false;

  displayValue.value = "";
  searchQuery.value = "";
  showDropdown.value = false;
  selectedIndex.value = -1;
  searchResults.value = [];
  emit("update:modelValue", "");
  emit("change", "", null);
};

// 暴露方法给父组件
defineExpose({
  clear,
  focus: () => {
    // 这里可以添加聚焦逻辑
  },
});
</script>

<style lang="scss" scoped>
.xen-autocomplete {
  position: relative;
  width: 100%;

  .autocomplete-input {
    width: 100%;
    height: 42px;
    border: 1px solid #e0e0e0;
    border-radius: 8px;
    padding: 0 12px;
    font-size: 14px;
    color: #333;
    box-sizing: border-box;
    line-height: 42px;
    transition:
      border-color 0.3s ease,
      background-color 0.3s ease;

    &:focus {
      border-color: #7881de;
      background: #ffffff;
      outline: none;
    }

    &::placeholder {
      color: #999;
    }

    &.has-error {
      border-color: #ff5252;
      background: #fff8f8;
    }

    &.is-focused {
      border-color: #7881de;
    }
  }

  .dropdown-list {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 1000;
    background: #ffffff;
    border: 1px solid #e0e0e0;
    border-top: none;
    border-radius: 0 0 8px 8px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    max-height: 200px;
    overflow: hidden;

    .dropdown-scroll {
      height: 100%;
      max-height: 200px;
    }

    .dropdown-item {
      padding: 12px;
      border-bottom: 1px solid #f0f0f0;
      cursor: pointer;
      transition: background-color 0.2s ease;

      &:last-child {
        border-bottom: none;
      }

      &:hover,
      &.is-selected {
        background: #f5f7ff;
      }

      .option-text {
        display: block;
        font-size: 14px;
        color: #333;
        line-height: 1.4;
      }

      .option-subtitle {
        display: block;
        font-size: 12px;
        color: #666;
        margin-top: 2px;
        line-height: 1.3;
      }
    }

    .no-results,
    .loading-item {
      padding: 12px;
      text-align: center;

      .no-results-text,
      .loading-text {
        font-size: 14px;
        color: #999;
      }
    }
  }
}
</style>
